﻿//using System.Collections;
//using System.Net;

//namespace LmgCMS.Service
//{
//    /// <summary>
//    /// 文件上传接口
//    /// </summary>
//    public interface IFileService
//    {
//        /// <summary>
//        /// 通过文件流上传文件方法
//        /// </summary>
//        /// <param name="byteData">文件字节数组</param>
//        /// <param name="fileName">文件名</param>
//        /// <param name="isThumbnail">是否生成缩略图</param>
//        /// <param name="isWater">是否打水印</param>
//        Task<FileDto> SaveAsync(byte[] byteData, string fileName, bool isThumbnail, bool isWater);

//        /// <summary>
//        /// 裁剪图片并保存
//        /// </summary>
//        Task<FileDto> CropAsync(string fileUri, int maxWidth, int maxHeight, int cropWidth, int cropHeight, int X, int Y);

//        /// <summary>
//        /// 保存远程文件到本地
//        /// </summary>
//        /// <param name="webRoot">站点的物理根目录</param>
//        /// <param name="sourceUri">URI地址</param>
//        /// <returns>上传后的路径</returns>
//        Task<FileDto> RemoteAsync(string sourceUri);
//    }
//    /// <summary>
//    /// 文件上传接口实现
//    /// </summary>
//    public class FileService: IFileService
//    {
//        private readonly ISysConfigService _configService;
//        public FileService(ISysConfigService configService)
//        {
//            _configService = configService;
//        }

//        /// <summary>
//        /// 通过文件流上传文件方法
//        /// </summary>
//        /// <param name="byteData">文件字节数组</param>
//        /// <param name="fileName">文件名</param>
//        /// <param name="isThumbnail">是否生成缩略图</param>
//        /// <param name="isWater">是否打水印</param>
//        public async Task<FileDto> SaveAsync(byte[] byteData, string fileName, bool isThumbnail, bool isWater)
//        {
//            //取得站点配置信息
//            var sysConfig = await _configService.QueryByTypeAsync(ConfigType.SysConfig);
//            if (sysConfig == null)
//            {
//                throw new ResponseException("系统配置信息不存在");
//            }
//            var config = JsonHelper.ToJson<SysConfigDto>(sysConfig.JsonData);
//            if (config == null)
//            {
//                throw new ResponseException("系统配置信息格式有误");
//            }

//            string fileExt = Path.GetExtension(fileName).Trim('.'); //文件扩展名，不含“.”
//            string newFileName = Guid.NewGuid() + "." + fileExt; //随机生成新的文件名
//            string newThumbnailFileName = "thumb_" + newFileName; //随机生成缩略图文件名

//            string upLoadPath = GetUpLoadPath(config); //本地上传目录相对路径
//            string fullUpLoadPath = FileHelper.GetWebPath(upLoadPath); //本地上传目录的物理路径
//            string newFilePath = upLoadPath + newFileName; //本地上传后的路径
//            string newThumbnailPath = upLoadPath + newThumbnailFileName; //本地上传后的缩略图路径

//            byte[]? thumbData = null; //缩略图文件流
//            FileDto fileDto = new(); //返回的对象

//            //检查文件字节数组是否为NULL
//            if (byteData == null)
//            {
//                throw new ResponseException("请选择要上传的文件");
//            }
//            //检查文件扩展名是否合法
//            if (!CheckFileExt(config, fileExt))
//            {
//                throw new ResponseException($"不允许上传{fileExt}类型的文件");
//            }
//            //检查文件大小是否合法
//            if (!CheckFileSize(config, fileExt, byteData.Length))
//            {
//                throw new ResponseException($"文件超过限制的大小");
//            }

//            //如果是图片，检查图片是否超出最大尺寸，是则裁剪
//            if (IsImage(fileExt) && (config.ImgMaxHeight > 0 || config.ImgMaxWidth > 0))
//            {
//                byteData = ImageHelper.MakeThumbnail(byteData, fileExt, config.ImgMaxWidth, config.ImgMaxHeight);
//            }
//            //如果是图片，检查是否需要生成缩略图，是则生成
//            if (IsImage(fileExt) && isThumbnail && config.ThumbnailWidth > 0 && config.ThumbnailHeight > 0)
//            {
//                thumbData = ImageHelper.MakeThumbnail(byteData, fileExt, config.ThumbnailWidth, config.ThumbnailHeight, config.ThumbnailMode);
//            }
//            else
//            {
//                newThumbnailPath = newFilePath; //不生成缩略图则返回原图
//            }
//            //如果是图片，检查是否需要打水印
//            if (IsWaterMark(config, fileExt) && isWater)
//            {
//                switch (config.WatermarkType)
//                {
//                    case 1:
//                        byteData = ImageHelper.LetterWatermark(byteData, fileExt, config.WatermarkText, config.WatermarkPosition,
//                            config.WatermarkImgQuality, config.WatermarkFont, config.WatermarkFontSize);
//                        break;
//                    case 2:
//                        byteData = ImageHelper.ImageWatermark(byteData, fileExt,
//                            FileHelper.GetWebPath(config.WatermarkPic), config.WatermarkPosition,
//                            config.WatermarkImgQuality, config.WatermarkTransparency);
//                        break;
//                }
//            }

//            //七牛云存储
//            if (config.FileServer.Equals("qiniu"))
//            {
//                if (!config.KodoBucket.IsNotNullOrEmpty() || !config.KodoDomain.IsNotNullOrEmpty() || !config.KodoAccessKey.IsNotNullOrEmpty() || !config.KodoSecretKey.IsNotNullOrEmpty())
//                {
//                    throw new ResponseException($"七牛云存储参数未设置");
//                }
//                //保存主文件
//                QiniuHelper.UploadFile(byteData, config.KodoAccessKey, config.KodoSecretKey, config.KodoBucket, newFilePath.TrimStart('/'));
//                //保存缩略图文件
//                if (thumbData != null)
//                {
//                    QiniuHelper.UploadFile(thumbData, config.KodoAccessKey, config.KodoSecretKey, config.KodoBucket, newThumbnailPath.TrimStart('/'));
//                }
//                //返回上传路径
//                fileDto.FilePath = config.KodoDomain + newFilePath;
//                if (isWater)
//                {
//                    fileDto.ThumbPath = new List<string>() { config.KodoDomain + newThumbnailPath }; //如果有缩略图
//                }
//            }
//            //阿里云存储
//            else if (config.FileServer.Equals("aliyun"))
//            {
//                if (!config.OssBucket.IsNotNullOrEmpty() || !config.OssDomain.IsNotNullOrEmpty() || !config.OssEndpoint.IsNotNullOrEmpty() || !config.OssAccessKey.IsNotNullOrEmpty() || !config.OssSecretKey.IsNotNullOrEmpty())
//                {
//                    throw new ResponseException($"阿里云存储参数未设置");
//                }
//                //保存主文件
//                OssHelper.UploadFile(byteData, config.OssEndpoint, config.OssAccessKey, config.OssSecretKey, config.OssBucket, newFilePath.TrimStart('/'));
//                //保存缩略图文件
//                if (thumbData != null)
//                {
//                    OssHelper.UploadFile(thumbData, config.OssEndpoint, config.OssAccessKey, config.OssSecretKey, config.OssBucket, newThumbnailPath.TrimStart('/'));
//                }
//                //返回上传路径
//                fileDto.FilePath = config.OssDomain + newFilePath;
//                if (isWater)
//                {
//                    fileDto.ThumbPath = new List<string>() { config.OssDomain + newThumbnailPath }; //如果有缩略图
//                }
//            }
//            //本地存储
//            else
//            {
//                //检查本地上传的物理路径是否存在，不存在则创建
//                if (!Directory.Exists(fullUpLoadPath))
//                {
//                    Directory.CreateDirectory(fullUpLoadPath);
//                }
//                //保存主文件
//                FileHelper.SaveFile(byteData, fullUpLoadPath + newFileName);
//                //保存缩略图文件
//                if (thumbData != null)
//                {
//                    FileHelper.SaveFile(thumbData, fullUpLoadPath + newThumbnailFileName);
//                }
//                //返回上传路径
//                fileDto.FilePath = newFilePath;
//                if (isWater)
//                {
//                    fileDto.ThumbPath = new List<string>() { newThumbnailPath }; //如果有缩略图
//                }
//            }
//            //返回成功信息
//            fileDto.FileName = fileName;
//            fileDto.FileSize = byteData.Length;
//            fileDto.FileExt = fileExt;
//            return fileDto;
//        }

//        /// <summary>
//        /// 裁剪图片并保存
//        /// </summary>
//        public async Task<FileDto> CropAsync(string fileUri, int maxWidth, int maxHeight, int cropWidth, int cropHeight, int X, int Y)
//        {
//            FileDto fileDto = new FileDto();//返回信息
//            string fileExt = Path.GetExtension(fileUri).Trim('.'); //文件扩展名，不含“.”
//            if (string.IsNullOrEmpty(fileExt) || !IsImage(fileExt))
//            {
//                throw new ResponseException($"该文件不是图片");
//            }

//            byte[]? byteData = null;
//            //判断是否远程文件
//            if (fileUri.ToLower().StartsWith("http://") || fileUri.ToLower().StartsWith("https://"))
//            {
//                using HttpClient client = new();
//                byteData = await client.GetByteArrayAsync(fileUri);
//            }
//            else //本地源文件
//            {
//                string fullName = FileHelper.GetWebPath(fileUri);
//                if (File.Exists(fullName))
//                {
//                    FileStream fs = File.OpenRead(fullName);
//                    BinaryReader br = new BinaryReader(fs);
//                    br.BaseStream.Seek(0, SeekOrigin.Begin);
//                    byteData = br.ReadBytes((int)br.BaseStream.Length);
//                    fs.Close();
//                }
//            }
//            if (byteData == null)
//            {
//                throw new ResponseException($"无法获取原图片");
//            }
//            //裁剪后得到文件流
//            byteData = ImageHelper.MakeThumbnail(byteData, fileExt, maxWidth, maxHeight, cropWidth, cropHeight, X, Y);
//            fileDto = await SaveAsync(byteData, fileUri, false, false);
//            await DeleteAsync(fileUri); //删除原图
//            return fileDto;
//        }

//        /// <summary>
//        /// 保存远程文件到本地
//        /// </summary>
//        /// <param name="sourceUri">URI地址</param>
//        /// <returns>上传后的路径</returns>
//        public async Task<FileDto> RemoteAsync(string sourceUri)
//        {
//            FileDto fileDto = new();//返回消息

//            if (!IsExternalIPAddress(sourceUri))
//            {
//                throw new ResponseException($"INVALID_URL");
//            }
//            using var response = await new HttpClient().GetAsync(sourceUri);
//            if (response == null)
//            {
//                throw new ResponseException($"抓取文件错误");
//            }
//            if (response.StatusCode != HttpStatusCode.OK)
//            {
//                throw new ResponseException($"Url returns{response?.StatusCode}, {response?.RequestMessage}");
//            }
//            if (response.Content.Headers.ContentType?.MediaType?.IndexOf("image") == -1)
//            {
//                throw new ResponseException($"Url is not an image");
//            }
//            byte[] byteData = await response.Content.ReadAsByteArrayAsync();
//            return await SaveAsync(byteData, sourceUri, false, false);
//        }

//        /// <summary>
//        /// 删除文件
//        /// </summary>
//        public async Task<bool> DeleteAsync(string fileUri)
//        {
//            //取得站点配置信息
//            var sysConfig = await _configService.QueryByTypeAsync(ConfigType.SysConfig);
//            if (sysConfig == null)
//            {
//                throw new ResponseException("站点配置信息不存在");
//            }
//            var config = JsonHelper.ToJson<SysConfigDto>(sysConfig.JsonData);
//            if (config == null)
//            {
//                throw new ResponseException("站点配置信息格式有误");
//            }
//            bool result = false;

//            //七牛云存储
//            if (config.FileServer.Equals("qiniu"))
//            {
//                if (!config.KodoBucket.IsNotNullOrEmpty() || !config.KodoDomain.IsNotNullOrEmpty() || !config.KodoAccessKey.IsNotNullOrEmpty() || !config.KodoSecretKey.IsNotNullOrEmpty())
//                {
//                    throw new ResponseException($"七牛云存储参数未设置");
//                }
//                //替换成相对路径
//                var filePath = fileUri.Replace(config.KodoDomain ?? String.Empty, string.Empty);
//                result = QiniuHelper.DeleteFile(config.KodoAccessKey, config.KodoSecretKey, config.KodoBucket, filePath.TrimStart('/'));
//            }
//            //阿里云存储
//            else if (config.FileServer.Equals("aliyun"))
//            {
//                if (!config.OssBucket.IsNotNullOrEmpty() || !config.OssDomain.IsNotNullOrEmpty() || !config.OssEndpoint.IsNotNullOrEmpty() || !config.OssAccessKey.IsNotNullOrEmpty() || !config.OssSecretKey.IsNotNullOrEmpty())
//                {
//                    throw new ResponseException($"阿里云存储参数未设置");
//                }
//                //替换成相对路径
//                var filePath = fileUri.Replace(config.OssDomain ?? String.Empty, string.Empty);
//                result = QiniuHelper.DeleteFile(config.KodoAccessKey, config.KodoSecretKey, config.KodoBucket, filePath.TrimStart('/'));
//            }
//            //本地存储
//            else
//            {
//                result = FileHelper.DeleteFile(FileHelper.GetWebPath(fileUri));
//            }
//            return false;
//        }

//        #region 辅助私有方法
//        /// <summary>
//        /// 返回上传目录相对路径
//        /// </summary>
//        private string GetUpLoadPath(SysConfigDto config)
//        {
//            string path = $"/{config.FilePath}/";
//            switch (config.FileSave)
//            {
//                case 1: //按年月日每天一个文件夹
//                    path += DateTime.Now.ToString("yyyyMMdd");
//                    break;
//                default: //按年月/日存入不同的文件夹
//                    path += DateTime.Now.ToString("yyyyMM") + "/" + DateTime.Now.ToString("dd");
//                    break;
//            }
//            return path + "/";
//        }

//        /// <summary>
//        /// 是否需要打水印
//        /// </summary>
//        private bool IsWaterMark(SysConfigDto config, string fileExt)
//        {
//            //判断是否开启水印
//            if (config.WatermarkType > 0)
//            {
//                //判断是否可以打水印的图片类型
//                ArrayList al = new ArrayList();
//                al.Add("bmp");
//                al.Add("jpeg");
//                al.Add("jpg");
//                al.Add("png");
//                if (al.Contains(fileExt.ToLower()))
//                {
//                    return true;
//                }
//            }
//            return false;
//        }

//        /// <summary>
//        /// 是否为图片文件
//        /// </summary>
//        /// <param name="fileExt">文件扩展名，不含“.”</param>
//        private bool IsImage(string fileExt)
//        {
//            ArrayList al = new ArrayList();
//            al.Add("bmp");
//            al.Add("jpeg");
//            al.Add("jpg");
//            al.Add("gif");
//            al.Add("png");
//            if (al.Contains(fileExt.ToLower()))
//            {
//                return true;
//            }
//            return false;
//        }

//        /// <summary>
//        /// 检查是否为合法的上传文件
//        /// </summary>
//        private bool CheckFileExt(SysConfigDto config, string fileExt)
//        {
//            //检查危险文件
//            string[] excExt = { "asp", "aspx", "ashx", "asa", "asmx", "asax", "php", "jsp", "htm", "html" };
//            for (int i = 0; i < excExt.Length; i++)
//            {
//                if (excExt[i].ToLower() == fileExt.ToLower())
//                {
//                    return false;
//                }
//            }
//            //检查合法文件
//            string[] allowExt = (config.FileExtension + "," + config.VideoExtension).Split(',');
//            for (int i = 0; i < allowExt.Length; i++)
//            {
//                if (allowExt[i].ToLower() == fileExt.ToLower())
//                {
//                    return true;
//                }
//            }
//            return false;
//        }

//        /// <summary>
//        /// 检查文件大小是否合法
//        /// </summary>
//        /// <param name="fileExt">文件扩展名，不含“.”</param>
//        /// <param name="fileSize">文件大小(B)</param>
//        private bool CheckFileSize(SysConfigDto config, string fileExt, int fileSize)
//        {
//            if (config.VideoExtension == null)
//            {
//                return false;
//            }
//            //将视频扩展名转换成ArrayList
//            ArrayList lsVideoExt = new ArrayList(config.VideoExtension.ToLower().Split(','));
//            //判断是否为图片文件
//            if (IsImage(fileExt))
//            {
//                if (config.ImgSize > 0 && fileSize > config.ImgSize * 1024)
//                {
//                    return false;
//                }
//            }
//            else if (lsVideoExt.Contains(fileExt.ToLower()))
//            {
//                if (config.VideoSize > 0 && fileSize > config.VideoSize * 1024)
//                {
//                    return false;
//                }
//            }
//            else
//            {
//                if (config.AttachSize > 0 && fileSize > config.AttachSize * 1024)
//                {
//                    return false;
//                }
//            }
//            return true;
//        }

//        /// <summary>
//        /// 检查文件地址是否文件服务器地址
//        /// </summary>
//        /// <param name="url">文件地址</param>
//        private bool IsExternalIPAddress(string url)
//        {
//            var uri = new Uri(url);
//            switch (uri.HostNameType)
//            {
//                case UriHostNameType.Dns:
//                    var ipHostEntry = Dns.GetHostEntry(uri.DnsSafeHost);
//                    foreach (IPAddress ipAddress in ipHostEntry.AddressList)
//                    {
//                        byte[] ipBytes = ipAddress.GetAddressBytes();
//                        if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
//                        {
//                            if (!IsPrivateIP(ipAddress))
//                            {
//                                return true;
//                            }
//                        }
//                    }
//                    break;

//                case UriHostNameType.IPv4:
//                    return !IsPrivateIP(IPAddress.Parse(uri.DnsSafeHost));
//            }
//            return false;
//        }

//        /// <summary>
//        /// 检查IP地址是否本地服务器地址
//        /// </summary>
//        /// <param name="myIPAddress">IP地址</param>
//        private bool IsPrivateIP(IPAddress myIPAddress)
//        {
//            if (IPAddress.IsLoopback(myIPAddress)) return true;
//            if (myIPAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
//            {
//                byte[] ipBytes = myIPAddress.GetAddressBytes();
//                // 10.0.0.0/24 
//                if (ipBytes[0] == 10)
//                {
//                    return true;
//                }
//                // 172.16.0.0/16
//                else if (ipBytes[0] == 172 && ipBytes[1] == 16)
//                {
//                    return true;
//                }
//                // 192.168.0.0/16
//                else if (ipBytes[0] == 192 && ipBytes[1] == 168)
//                {
//                    return true;
//                }
//                // 169.254.0.0/16
//                else if (ipBytes[0] == 169 && ipBytes[1] == 254)
//                {
//                    return true;
//                }
//            }
//            return false;
//        }
//        #endregion
//    }
//}
